#ifdef TEST
#include "ScanBuffer.h"
//#include "BufferBlock.h"
#include <iostream>
#include <cstdlib> //NULL
#include <fcntl.h>


#ifdef WIN32
	#define READ_CMD(fd, buf, size) _read((fd),(buf),(size))
	#define OPEN_CMD(file, option) _open((file),(option))
#else
	#define READ_CMD(fd, buf, size) read((fd),(buf),(size))
	#define OPEN_CMD(file, option) open((file),(option))
#endif


ScanBufferList::ScanBufferList(char* filename, int blockSize) {
	this->blockSize = blockSize;
	this->filename = filename;
	
	this->blockCount = 0;
	this->charCount = 0;
	this->delCharCount = 0;
	this->lineCount = 0;
	this->columnCount = 0;
	this->first = NULL;
	this->last = NULL;
	this->current = NULL;
	this->currentChars = 0;
	
	this->fd = OPEN_CMD(filename, O_RDONLY);
	
	if(this->fd == -1) {
		throw ScanBufferIOException("File not found!");
	}
			
	this->createNewBlock();

}

ScanBufferList::~ScanBufferList() {
	close(this->fd);
}

unsigned int ScanBufferList::getLine() {
	return this->lineCount;
}

unsigned int ScanBufferList::getColumn() {
	return this->columnCount;
}

void ScanBufferList::createNewBlock() {
	char* buffer = new char[this->blockSize];
	int eof_size = 0;
	int ret = READ_CMD(this->fd, buffer, this->blockSize);
	
	if(ret < this->blockSize) { // EOF reached
		char* tmp = buffer;
		while(*tmp++) {
			eof_size++;
		}
		std::cout << "bla" << eof_size;
		eof_size-=1;
	}
	
	
	
	BufferBlock* newBlock = new BufferBlock(this->blockSize, buffer, eof_size);
	
	// Append new block to list
	if(this->first == NULL) {
		this->first = newBlock;
		this->last = newBlock;
	} else {
			this->last->setNextBlock(newBlock);
			newBlock->setPrevBlock(this->last);
			this->last = newBlock;
	}
	
	this->current = newBlock;
	this->blockCount++;
	
	//std::cout << "Block:" << this->blockCount << std::endl;

}

char ScanBufferList::getNextChar() {
	
	if(this->current != this->last && this->current->getStatus() == 1) {
		this->current = this->current->getNextBlock();
	}
	
	if(this->current == this->last && this->current->getStatus() == 1) {
		this->createNewBlock();
	}
	
	
	
	char c = this->current->getNextChar();
	if( c == '\n') {
		this->lineCount++;
		this->columnCount=0;
	}
	this->currentChars++;
	this->columnCount++;

	//std::cout << c;
	
	return c;
	
}


void ScanBufferList::rewind(int count) {
	this->charCount -= count;
	this->columnCount -= count;
	this->current = this->current->rewindChars(count);
}

void ScanBufferList::setProcessedChars(int count) {
	this->delCharCount += count;
	this->currentChars = 0;
	while(this->first != this->current && this->first != this->last && this->delCharCount >= this->blockSize) {
	
		
			BufferBlock* tmp = this->first->getNextBlock();
			delete this->first;
			this->first = tmp;
			this->first->setPrevBlock(0);
			
			this->delCharCount -= this->blockSize;
			this->blockCount--;
		
	}
}

void ScanBufferList::reset() {
	this->setProcessedChars(this->currentChars);
}

void ScanBufferList::unGetChar() {
		this->rewind(1),
		this->setProcessedChars(this->charCount-1);
}

char* ScanBufferList::getCurrentLexem() {
	return "";
}
	

#endif